/* ********************************************************************************
 *		Copyright:  (C) 2025 ZYT
 *                  All rights reserved.
 *
 *       Filename:  socket.c
 *    Description:  This file 
 *                        
 *        Version:  1.0.0(30/03/25)
 *         Author:  Zhang yuting <zhangyuting@163.com>
 *      ChangeLog:  1, Release initial version on "30/03/25 16:37:09"
 *                            
 *********************************************************************************/

#include "socket.h"

int socket_connect(char *serv_ip, int serv_port)
{
	int                 sockfd = -1;
	struct addrinfo    	hints, *result, *rp;
	int                 rv = -1;
	char				port_str[16];

	// 将端口号转换为字符串
	snprintf(port_str, sizeof(port_str), "%d", serv_port);

	// 设置 hints 结构体
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;     // 允许 IPv4 或 IPv6
	hints.ai_socktype = SOCK_STREAM; // 流式套接字
	hints.ai_protocol = IPPROTO_TCP; // TCP 协议

	// 执行 DNS 解析（保持 serv_ip 为 char* 类型）
	if ((rv = getaddrinfo(serv_ip, port_str, &hints, &result)) != 0) 
	{
		dbg_printf("DNS resolution failed: %s\n", gai_strerror(rv));
		return -1;
	}

	// 遍历所有可能的地址
	for (rp = result; rp != NULL; rp = rp->ai_next) 
	{
		// 创建套接字
		sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (sockfd == -1) 
		{
			continue;  // 尝试下一个地址
		}

		// 尝试连接
		if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0) 
		{
			dbg_printf("Connected successfully\n");
			break;     // 连接成功
		}

		// 连接失败则关闭套接字继续尝试
			close(sockfd);
			sockfd = -1;
	}

	// 释放地址信息内存
		freeaddrinfo(result);

	// 所有地址尝试失败
		if (sockfd == -1) {
			dbg_printf("Could not connect to any address: %s\n", strerror(errno));
			return -2;
		}

	return sockfd;
}



int socket_check(int sockfd)
{
	struct tcp_info    info;
	int                len = sizeof(info);

	getsockopt(sockfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&len);
	
	if(info.tcpi_state == TCP_ESTABLISHED)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}


int socket_write(int fd, char *data, int len)
{
	int         rv = -1;
	int         left_bytes = len;
	int         i = 0;

	if(  !data || len <= 0 )     
	{           
		return -1;
	}              

	log_debug("start write to server");

	while( left_bytes > 0 )
	{
		rv = write(fd, &data[i], left_bytes);
		if ( rv < 0 )
		{
			log_warn("write to server by fd[%d] failure: %s\n", fd, strerror(errno));
			close(fd);
			return -1;
		}
		else if ( rv == 0 )
		{
			log_debug("sent over\n");
			return 0;
		}

		i += rv;
		left_bytes -= rv;
		continue;
	}
	return 0;
}
